<template>
  <div class="dong-tooltip" v-on="outEvent">
    <!-- 触发的元素，设置为一个插槽 -->
    <div class="dong-tooltip__trigger" ref="reference" v-on="events">
      <slot />
    </div>
    <!-- 要显示的提示内容 -->
    <!-- 考虑有些时候提示内容会比较复杂，因此这里仍然是提供插槽的形式 -->
    <div class="dong-tooltip__popper" :data-popper-placement="placement" :style="floatingStyles" ref="floating"
      v-if="isOpen">
      <slot name="content">
        {{ content }}
      </slot>
      <!-- 箭头 -->
      <div id="arrow"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { debounce } from 'lodash-es';
import {
  useFloating,
  offset,
  flip,
  shift,
} from '@floating-ui/vue';
import propsObj from './props'
defineOptions({ name: 'DongTooltip' })
const props = defineProps(propsObj)
const reference = ref(null)
const floating = ref(null)
const { floatingStyles } = useFloating(reference, floating, {
  placement: props.placement,
  middleware: [offset(10), flip(), shift()],
});
const emit = defineEmits(['visible-change'])
// 首先，提示框是否要显示出来，我们这里需要一个变量来控制
const isOpen = ref(false)
let events = reactive({})
let outEvent = reactive({})
const openDebounce = debounce(() => {
  isOpen.value = true
  emit('visible-change', true)
}, props.openDelay)
const closeDebounce = debounce(() => {
  isOpen.value = false
  emit('visible-change', false)
}, props.closeDelay)
const open = () => {
  closeDebounce.cancel()
  openDebounce()
}
const close = () => {
  openDebounce.cancel()
  closeDebounce()
}
// 接下来我们需要给我们的触发元素绑定相应事件
// 调用 attachEvents 方法，就能够给触发元素绑定事件
const attachEvents = () => {
  if (props.trigger === 'hover') {
    events['mouseenter'] = open
    outEvent['mouseleave'] = close
  } else if (props.trigger === 'click') {
    events['click'] = () => {
      isOpen.value ? close() : open()
    }
  }
}
// 这里我们需要判断用户是否要自定义处理
// 只有在用户不需要自定义处理的时候，我们才绑定事件
if (!props.manual) {
  attachEvents()
}
defineExpose({
  show: open,
  hide: close
})
</script>

<style lang="scss" scoped></style>
